import logging
import logging.handlers
import requests
import json
import time
from typing import Dict, Any, Optional, Tuple
from pathlib import Path
from datetime import datetime

class LogManager:
    """日志管理器"""
    _loggers = {}
    _initialized = False
    
    @classmethod
    def initialize_logging(cls, level: str = "INFO", format_str: str = None):
        """初始化日志系统"""
        if cls._initialized:
            return
            
        # 设置日志级别
        log_level = getattr(logging, level.upper(), logging.INFO)
        
        # 设置日志格式
        if format_str is None:
            format_str = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        
        formatter = logging.Formatter(format_str)
        
        # 创建logs目录
        logs_dir = Path("logs")
        logs_dir.mkdir(exist_ok=True)
        
        # 配置根日志器
        root_logger = logging.getLogger()
        root_logger.setLevel(log_level)
        
        # 清除现有处理器
        root_logger.handlers.clear()
        
        # 控制台处理器
        console_handler = logging.StreamHandler()
        console_handler.setLevel(log_level)
        console_handler.setFormatter(formatter)
        root_logger.addHandler(console_handler)
        
        # 文件处理器
        file_handler = logging.handlers.RotatingFileHandler(
            logs_dir / "edge.log",
            maxBytes=10*1024*1024,  # 10MB
            backupCount=5,
            encoding='utf-8'
        )
        file_handler.setLevel(log_level)
        file_handler.setFormatter(formatter)
        root_logger.addHandler(file_handler)
        
        cls._initialized = True
    
    @classmethod
    def get_logger(cls, name: str) -> logging.Logger:
        """获取指定名称的日志器"""
        if name not in cls._loggers:
            cls._loggers[name] = logging.getLogger(name)
        return cls._loggers[name]

class HTTPClient:
    """HTTP客户端封装"""
    
    def __init__(self, base_url: str, timeout: int = 30, max_retries: int = 3):
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        self.max_retries = max_retries
        self.session = requests.Session()
        
        # 配置连接池和重试机制
        adapter = requests.adapters.HTTPAdapter(
            pool_connections=10,
            pool_maxsize=20,
            max_retries=requests.adapters.Retry(
                total=max_retries,
                backoff_factor=0.3,
                status_forcelist=[500, 502, 503, 504]
            )
        )
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)
        
        self.logger = LogManager.get_logger("HTTPClient")
    
    def get(self, endpoint: str, params: Dict = None) -> Tuple[bool, Dict]:
        """发送GET请求"""
        return self._request("GET", endpoint, params=params)
    
    def post(self, endpoint: str, data: Dict = None, json_data: Dict = None, files: Dict = None) -> Tuple[bool, Dict]:
        """发送POST请求"""
        return self._request("POST", endpoint, data=data, json=json_data, files=files)
    
    def put(self, endpoint: str, data: Dict = None, json_data: Dict = None) -> Tuple[bool, Dict]:
        """发送PUT请求"""
        return self._request("PUT", endpoint, data=data, json=json_data)
    
    def delete(self, endpoint: str) -> Tuple[bool, Dict]:
        """发送DELETE请求"""
        return self._request("DELETE", endpoint)
    
    def _request(self, method: str, endpoint: str, **kwargs) -> Tuple[bool, Dict]:
        """发送HTTP请求的通用方法"""
        url = f"{self.base_url}/{endpoint.lstrip('/')}"
        start_time = time.time()
        
        try:
            self.logger.debug(f"发送{method}请求: {url}")
            
            response = self.session.request(
                method=method,
                url=url,
                timeout=self.timeout,
                **kwargs
            )
            
            elapsed_time = time.time() - start_time
            
            # 处理响应
            if response.status_code in [200, 201, 202]:
                try:
                    result = response.json()
                    self.logger.debug(f"请求成功: {method} {url} - {response.status_code} - 耗时: {elapsed_time:.2f}s")
                    return True, result
                except json.JSONDecodeError:
                    # 如果不是JSON响应，返回文本
                    self.logger.debug(f"请求成功(非JSON): {method} {url} - {response.status_code} - 耗时: {elapsed_time:.2f}s")
                    return True, {"text": response.text}
            else:
                self.logger.error(f"请求失败: {method} {url} - {response.status_code} - 耗时: {elapsed_time:.2f}s - 响应: {response.text[:200]}")
                try:
                    error_data = response.json()
                    error_data["http_status"] = response.status_code
                    error_data["elapsed_time"] = elapsed_time
                except:
                    error_data = {
                        "error": response.text,
                        "http_status": response.status_code,
                        "elapsed_time": elapsed_time
                    }
                return False, error_data
                
        except requests.exceptions.Timeout:
            elapsed_time = time.time() - start_time
            self.logger.error(f"请求超时: {method} {url} - 耗时: {elapsed_time:.2f}s (超时阈值: {self.timeout}s)")
            return False, {"error": "请求超时", "timeout": self.timeout, "elapsed_time": elapsed_time}
        except requests.exceptions.ConnectionError as e:
            elapsed_time = time.time() - start_time
            self.logger.error(f"连接错误: {method} {url} - 耗时: {elapsed_time:.2f}s - 错误: {str(e)}")
            return False, {"error": "连接错误", "detail": str(e), "elapsed_time": elapsed_time}
        except Exception as e:
            elapsed_time = time.time() - start_time
            self.logger.error(f"请求异常: {method} {url} - 耗时: {elapsed_time:.2f}s - 错误: {str(e)}")
            return False, {"error": str(e), "elapsed_time": elapsed_time}

class FileManager:
    """文件管理工具"""
    
    def __init__(self):
        self.logger = LogManager.get_logger("FileManager")
    
    def move_file(self, src: Path, dst: Path) -> bool:
        """移动文件"""
        try:
            import shutil
            # 确保目标目录存在
            dst.parent.mkdir(parents=True, exist_ok=True)
            
            # 移动文件
            #src.rename(dst)
            shutil.move(str(src), str(dst))
            self.logger.debug(f"文件移动成功: {src} -> {dst}")
            return True
            
        except Exception as e:
            self.logger.error(f"文件移动失败: {src} -> {dst}, 错误: {str(e)}")
            return False
    
    def copy_file(self, src: Path, dst: Path) -> bool:
        """复制文件"""
        try:
            import shutil
            
            # 确保目标目录存在
            dst.parent.mkdir(parents=True, exist_ok=True)
            
            # 复制文件
            shutil.copy2(src, dst)
            self.logger.debug(f"文件复制成功: {src} -> {dst}")
            return True
            
        except Exception as e:
            self.logger.error(f"文件复制失败: {src} -> {dst}, 错误: {str(e)}")
            return False
    
    def list_files(self, directory: Path, pattern: str = "*") -> list:
        """列出目录中的文件"""
        try:
            if not directory.exists():
                return []
            
            files = list(directory.glob(pattern))
            files = [f for f in files if f.is_file()]
            return sorted(files)
            
        except Exception as e:
            self.logger.error(f"列出文件失败: {directory}, 错误: {str(e)}")
            return []
    
    def create_zip(self, source_dir: Path, zip_path: Path, exclude_patterns: list = None) -> bool:
        """创建ZIP文件"""
        try:
            import zipfile
            
            if exclude_patterns is None:
                exclude_patterns = []
            
            zip_path.parent.mkdir(parents=True, exist_ok=True)
            
            with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
                for file_path in source_dir.rglob('*'):
                    if file_path.is_file():
                        # 检查是否需要排除
                        should_exclude = False
                        for pattern in exclude_patterns:
                            if pattern in str(file_path):
                                should_exclude = True
                                break
                        
                        if not should_exclude:
                            arcname = file_path.relative_to(source_dir)
                            zipf.write(file_path, arcname)
            
            self.logger.debug(f"ZIP文件创建成功: {zip_path}")
            return True
            
        except Exception as e:
            self.logger.error(f"ZIP文件创建失败: {zip_path}, 错误: {str(e)}")
            return False

class MetricsCollector:
    """系统指标收集器"""
    
    def __init__(self):
        self.logger = LogManager.get_logger("MetricsCollector")
    
    def get_system_metrics(self) -> Dict[str, Any]:
        """获取系统指标"""
        metrics = {
            "timestamp": datetime.now().isoformat(),
            "cpu_load": 0.0,
            "memory_load": 0.0,
            "disk_usage": 0.0,
            "network_load": 0.0
        }
        
        try:
            import psutil
            
            # CPU使用率
            metrics["cpu_load"] = psutil.cpu_percent(interval=1)
            
            # 内存使用率
            memory = psutil.virtual_memory()
            metrics["memory_load"] = memory.percent
            
            # 磁盘使用率
            disk = psutil.disk_usage('/')
            metrics["disk_usage"] = (disk.used / disk.total) * 100
            
            # 网络负载（简化处理）
            network = psutil.net_io_counters()
            metrics["network_bytes_sent"] = network.bytes_sent
            metrics["network_bytes_recv"] = network.bytes_recv
            
        except ImportError:
            self.logger.warning("psutil未安装，无法获取系统指标")
        except Exception as e:
            self.logger.error(f"获取系统指标失败: {str(e)}")
        
        return metrics

# 全局工具实例
file_manager = FileManager()
metrics_collector = MetricsCollector() 